package com.tianji.remark.task;

import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.remark.service.ILikedRecordService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

import static com.tianji.remark.constants.RedisConstants.LIKE_BIZ_KEY_PREFIX;

@Component

public class CountLikedNums {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ILikedRecordService recordService;
    private static final List<String> BIZ_TYPES = List.of("QA", "NOTE");
    private static final Integer MaxSize=30;
    private final static String ALL_KEY=LIKE_BIZ_KEY_PREFIX+"*";
    @Resource
    private  RabbitMqHelper rabbitMqHelper;


    @Scheduled(fixedRate = 10000)
    public void checkLikedTimes(){
        //遍历每个业务类型
        for (String bizType : BIZ_TYPES) {
            recordService.readLikedTimesAndSendMessage(bizType,MaxSize);
        }
    }
    @Scheduled(fixedRate = 10000*60*60)//每一个小时执行一次
    public void ReadRedisToSQL() {
        for (String bizType : BIZ_TYPES) {
            recordService.sendToMySQL(bizType,MaxSize);
        }
    }
    /**
    * 在添加或者取消点赞业务中，因为这个业务用户使用率比较大，如果每次都将数据存到数据库，并且访问数据库会给数据库造成很大的压力
     * 所以在这个功能中我们选择将点赞数据存入redis中，在利用mq异步转发给其他微服务，在存入redis数据结构上我们选择了zset结构，
     * 我们将zset的key设置为前缀＋业务id，member为业务的类型，score为用户id，这样可以保证每个评论或者每个回答的每个用户都会有一次点赞次数或者取消次数，
     * 接着我们使用springTask定时任务来处理mq以及将redis中的数据存入数据库中
     * 怎么存的？
     * 我们使用zset中的scan方法全文检索获得所有的key，然后通过循环获取每个key的后缀，即业务id，并且通过zset的rangewithscores方法
     * 获取每个key的用户信息以及业务类型，将其封装成集合，一次性批量插入数据库，mq的发送消息我们也采用了集合形式批量发送，这样可以减少mq压力
    * */

    /*@Scheduled(fixedRate = 20000) // 20s
    @Transactional
    public void checkLikedTimes(){
        ArrayList<String> list = new ArrayList<>();
        //通过scan获取所有的key  LIKE_BIZ_KEY_PREFIX+bizId
        try
            (Cursor<String> scan = stringRedisTemplate.scan(ScanOptions.scanOptions().match(ALL_KEY).build())){
            while (scan.hasNext()){
                String key = scan.next();
                    list.add(key);
            }
        }

        for (String bitIdKey : list) {
            //1.截取key后缀,获取每个bizId
            String bizId = bitIdKey.substring(LIKE_BIZ_KEY_PREFIX.length());
            //2.查询点赞记录,查询该key的所有值，从0到-1  zset结构：bizId, bizType, userId 所以同一个key 中的值，就是同一个业务类型，
            //因为每个用户对同一个评论或回答的点赞记录，只会有一条记录，所以每个zset可能key相同，type相同，但如果这两个相同，那么他的userId一定不同
            ArrayList<LikedRecord> likedRecords = new ArrayList<>();
            Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().rangeWithScores(bitIdKey, 0, -1);
            int count=0;
            for (ZSetOperations.TypedTuple<String> tuple : typedTuples) {
                String bizType = tuple.getValue();
                Long userId = (long) Math.floor(tuple.getScore()==null?0:tuple.getScore());
                    count++;
                LikedRecord record = new LikedRecord();
                record.setBizId(Long.parseLong(bizId));
                record.setBizType(bizType);
                record.setUserId(userId);
                likedRecords.add(record);

            }
            //3.保存到数据库中
            Set<String> existingKeys = new HashSet<>();

            // 查询数据库中已存在的 (bizId, userId) 组合
            List<LikedRecord> existingRecords = recordService.lambdaQuery()
                    .in(LikedRecord::getBizId, likedRecords.stream().map(LikedRecord::getBizId).collect(Collectors.toList()))
                    .list();
            existingRecords.forEach(record -> existingKeys.add(record.getBizId() + "-" + record.getUserId()));

            // 过滤掉已存在的记录
            List<LikedRecord> filteredRecords = likedRecords.stream()
                    .filter(record -> !existingKeys.contains(record.getBizId() + "-" + record.getUserId()))
                    .collect(Collectors.toList());

            // 批量保存过滤后的记录
            if (!filteredRecords.isEmpty()) {
                recordService.saveBatch(filteredRecords);
            }
            //4.查询数据库某个评论或者回答点赞次数
            LikedTimesDTO dto = new LikedTimesDTO();
            dto.setBizId(Long.parseLong(bizId));
            dto.setLikedTimes(count);
            rabbitMqHelper.send(
                    MqConstants.Exchange.LIKE_RECORD_EXCHANGE,
                    StringUtils.format(MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE, likedRecords.get(0).getBizType()),
                    dto
            );
        }
    }*/
}
